package com.plexobject.rbac.utils; import java.io.IOException; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.Key; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.SecureRandom; import java.security.Security; import java.security.spec.InvalidKeySpecException; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; import javax.crypto.SecretKeyFactory; import javax.crypto.ShortBufferException; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.PBEKeySpec; import javax.crypto.spec.PBEParameterSpec; import javax.crypto.spec.SecretKeySpec; import sun.misc.BASE64Decoder; import sun.misc.BASE64Encoder; import com.plexobject.rbac.Configuration; public class PasswordUtils { private static final byte[] KEY_BYTES = new byte[] { 0x73, 0x2f, 0x2d, 0x33, (byte) 0xc8, 0x01, 0x73, 0x2b, 0x72, 0x06, 0x75, 0x6c, (byte) 0xbd, 0x44, (byte) 0xf9, (byte) 0xc1, (byte) 0xc1, 0x03, (byte) 0xdd, (byte) 0xd9, 0x7c, 0x7c, (byte) 0xbe, (byte) 0x8e }; private static final String ENCRYPTION_PASSWORD = Configuration .getInstance().getProperty("encryption_credentials", "credentials"); private static final byte[] IV_BYTES = new byte[] { (byte) 0xb0, 0x7b, (byte) 0xf5, 0x22, (byte) 0xc8, (byte) 0xd6, 0x08, (byte) 0xb8 }; static { Security .addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); } public static String generateCredentials() { // Uses a secure Random not a simple Random try { SecureRandom random = SecureRandom.getInstance("SHA1PRNG"); // generation 96 bits long byte[] bytes = new byte[12]; random.nextBytes(bytes); // Digest computation String credentials = byteToBase64(bytes); return getHash(credentials); } catch (NoSuchAlgorithmException e) { throw new RuntimeException(e); } } public static String encrypt(String text) throws NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException, InvalidKeyException, ShortBufferException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException { byte[] input = text.getBytes(); SecretKeySpec key = new SecretKeySpec(KEY_BYTES, "DESede"); Cipher cipher = Cipher.getInstance("DESede/CBC/PKCS7Padding", "BC"); // encryption pass cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(IV_BYTES)); byte[] cipherText = cipher.doFinal(input); return new String(cipherText); } public static String decrypt(String text) throws NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException, InvalidKeyException, ShortBufferException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException, InvalidKeySpecException { final byte[] cipherText = text.getBytes(); // decryption pass // Cipher cipher = Cipher.getInstance("DESede/CBC/PKCS7Padding", "BC"); // SecretKeySpec key = new SecretKeySpec(ENCRYPTION_KEY, "DESede"); // cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(IV_BYTES)); // // byte[] plainText = new byte[cipherText.length]; // int ptLength = cipher.update(cipherText, 0, cipherText.length, // plainText, 0); // ptLength += cipher.doFinal(plainText, ptLength); // decrypt the data using PBE byte[] salt = new byte[] { 0x7d, 0x60, 0x43, 0x5f, 0x02, (byte) 0xe9, (byte) 0xe0, (byte) 0xae }; int iterationCount = 2048; PBEKeySpec pbeSpec = new PBEKeySpec(ENCRYPTION_PASSWORD.toCharArray()); SecretKeyFactory keyFact = SecretKeyFactory.getInstance( "PBEWithSHAAnd3KeyTripleDES", "BC"); Cipher cipher = Cipher.getInstance("PBEWithSHAAnd3KeyTripleDES", "BC"); Key sKey = keyFact.generateSecret(pbeSpec); cipher.init(Cipher.DECRYPT_MODE, sKey, new PBEParameterSpec(salt, iterationCount)); return new String(cipher.doFinal(cipherText)); } /** * From a base 64 representation, returns the corresponding byte[] * * @param data * String The base64 representation * @return byte[] * @throws IOException */ public static byte[] base64ToByte(String data) throws IOException { BASE64Decoder decoder = new BASE64Decoder(); return decoder.decodeBuffer(data); } /** * From a byte[] returns a base 64 representation * * @param data * byte[] * @return String * @throws IOException */ public static String byteToBase64(byte[] data) { BASE64Encoder endecoder = new BASE64Encoder(); return endecoder.encode(data); } public static String getHash(String credentials) { try { MessageDigest digest = MessageDigest.getInstance("SHA-1"); digest.reset(); byte[] input = digest.digest(credentials.getBytes()); return byteToBase64(input); } catch (NoSuchAlgorithmException e) { throw new RuntimeException(e); } } }